package com.yt.quotes.api.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.LineIterator;

import com.yt.quotes.api.bean.Equity;
import com.yt.quotes.api.bean.QuoteResult;
import com.yt.quotes.api.config.Config;
import com.yt.quotes.api.util.Entry;
import com.yt.quotes.api.util.HTTPUtil;
import com.yt.quotes.api.util.XMLUtil;

public class QuotesAPIForYahoo implements QuotesAPI {
	private final static String YAHOO_Field_MAPPING_FILE="FieldMappingForYahoo.xml";
	private final static String COMMON_FILEDS_KEY="commonFileds";
	private final static String YAHOO_FILEDS_KEY="yahooFileds";
	
	private final static String YAHOO_QUOTE_DATA_URL=Config.getInstance().getProperty("yahoo-quote-data-url");
	private final static String YAHOO_CHART_DATA_URL=Config.getInstance().getProperty("yahoo-chart-data-url");
	
	private final static Map<String,String> delayedFieldMapping=new HashMap<String,String>();
	private final static Map<String,String> realtimeFieldMapping=new HashMap<String,String>();
	
	
	static{
		initFieldMapping();
	}

	private static void initFieldMapping() {
		try {
			Entry entry=XMLUtil.parseFile(YAHOO_Field_MAPPING_FILE);
			List<Entry> list=entry.retrieveSubEntries("Field");
			for(Entry e:list){
				String id=e.attribute("id");
				String d=e.attribute("d");
				String r=e.attribute("r");
				delayedFieldMapping.put(id, d);
				if(r!=null){
					realtimeFieldMapping.put(id, r);
				}else{
					realtimeFieldMapping.put(id, d);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Map<String,String> mappingFields(String fields, Map<String, String> fieldMapping) {
		if(fields==null||fields.length()==0){
			fields=DEFAULT_FIELDS;
		}else{
			if(fields.indexOf("symbol")==-1){
				fields="symbol,"+fields;
			}
		}
		String[] fieldArray=fields.split(",");
		StringBuilder yahooFileds=new StringBuilder();
		StringBuilder commonFileds=new StringBuilder();
		for(int i=0,l=fieldArray.length;i<l;i++){
			String field=fieldArray[i].toLowerCase();
			if(fieldMapping.containsKey(field)){
				yahooFileds.append(fieldMapping.get(field));
				commonFileds.append(field);
				if(i!=l-1){
					commonFileds.append(",");
				}
			}
		}
		Map<String,String> map=new HashMap<String,String>();
		map.put(COMMON_FILEDS_KEY, commonFileds.toString());
		map.put(YAHOO_FILEDS_KEY, yahooFileds.toString());
		return map;
	}
	
	private String formatQuoteURL(String instrument,String fields){
		String quoteURL=YAHOO_QUOTE_DATA_URL;
		if(instrument!=null&&instrument.length()!=0){
			quoteURL+="?s="+instrument.replaceAll(",", "+");
			if(!fields.equals("")){
				quoteURL+="&f="+fields;
			}			
			return quoteURL;
		}
		return null;
	}
	
	private Equity fillEquity(String line,String[] fieldsArray){
		Equity e=new Equity();
		Map<String,String> fields=new HashMap<String,String>();
		String[] lineArray=line.split(",");
		for(int i=0,l=fieldsArray.length;i<l;i++){
			if(fieldsArray[i].equalsIgnoreCase("symbol")){
				e.setSymbol(lineArray[i]);
			}else{
				fields.put(fieldsArray[i], lineArray[i]);
			}
		}
		e.setFields(fields);
		System.out.print(e);
		return e;
	}
	
	public QuoteResult obtainQuotes(String instrument, String fields,boolean isDelayed) {
		Map<String,String> fieldsMapping=mappingFields(fields,isDelayed?delayedFieldMapping:delayedFieldMapping);
		String quoteURL=formatQuoteURL(instrument,fieldsMapping.get(YAHOO_FILEDS_KEY));
		if(quoteURL!=null){
			try {
				System.out.println(quoteURL);
				String[] fieldsArray=fieldsMapping.get(COMMON_FILEDS_KEY).split(",");
				LineIterator it=HTTPUtil.parse(quoteURL);
				List<Equity> quotes=new ArrayList<Equity>();
				while(it.hasNext()){
					String line=it.nextLine();
					Equity e=fillEquity(line,fieldsArray);
					quotes.add(e);
				}
				if(quotes.size()>0){
					QuoteResult qr=new QuoteResult();
					qr.setQuotes(quotes);
					return qr;
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		
		return null;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		QuotesAPI api=new QuotesAPIForYahoo();
		api.obtainQuotes("MSFT,IBM", "lastvolume,volume,52wkhigh,52wklow,mktcap,exch" , true);
	}

}
